#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>

#ifdef Q_OS_WIN
    #define FILENAME "../test/out.yuv"
#else
    #define FILENAME "/Users/zuojie/QtProjects/audio-video-dev/test/in.yuv"
#endif

// 出错了就执行goto end
#define RET(judge, func) \
    if (judge) { \
        qDebug() << #func << "Error" << SDL_GetError(); \
        return; \
    }

#define PIXEL_FORMAT SDL_PIXELFORMAT_IYUV
#define IMG_W 848
#define IMG_H 480


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    _widget = new QWidget(this);
    _widget->setGeometry(0,50,IMG_W,IMG_H);

    // 初始化Video子系统
    RET(SDL_Init(SDL_INIT_VIDEO),SDL_Init);

    // 创建窗口
    _window  = SDL_CreateWindowFrom((void *)_widget->winId());
    RET(!_window, SDL_CreateWindow);

    // 创建渲染上下文（默认的渲染目标是window）
    _renderer = SDL_CreateRenderer(_window,
                       // 要初始化的渲染设备的索引，设置 -1 则初始化第一个支持 flags 的设备
                       -1,
                       SDL_RENDERER_ACCELERATED |
                       SDL_RENDERER_PRESENTVSYNC);
    if (!_renderer) { // 说明开启硬件加速失败
        _renderer = SDL_CreateRenderer(_window, -1, 0);
    }
    RET(!_renderer, SDL_CreateRenderer);

    // 创建纹理
    _texture = SDL_CreateTexture(_renderer,
                                //显示的像素数据格式，我们显示的YUV图片像素格式是yuv420p，
                                //其实SDL_PIXELFORMAT_IYUV就是yuv420p像素格式
                                PIXEL_FORMAT,
                                //之前我们把同一个texture在窗口绘制多次时，我们设置的是SDL_TEXTUREACCESS_TARGET，
                                //这里我们设置SDL_TEXTUREACCESS_STATIC，当然设置成SDL_TEXTUREACCESS_STREAMING也可以
                                SDL_TEXTUREACCESS_STATIC,
                                IMG_W,IMG_H);
    RET(!_texture, SDL_CreateTexture);

    // 打开文件
    _file.setFileName(FILENAME);
    if(!_file.open(QFile::ReadOnly)){
        qDebug() << "file open error" << FILENAME;
    }
}

MainWindow::~MainWindow()
{
    delete ui;
    _file.close();
    SDL_DestroyTexture(_texture);
    SDL_DestroyRenderer(_renderer);
    SDL_DestroyWindow(_window);
    SDL_Quit();
}

void MainWindow::on_playButton_clicked(){
    // 开启定时器
     _timerId = startTimer(1000 /30.0);
}

// 每隔一段时间就会调用
void MainWindow::timerEvent(QTimerEvent *event){
    // yuv420p 像素格式每个像素占 1.5 字节
    int imgSize = IMG_W * IMG_H * 1.5;
    char data[imgSize];
    // 每次读取一帧图像
    if(_file.read(data,imgSize) > 0){
        // 将YUV的像素数据填充到texture
        RET(SDL_UpdateTexture(_texture,
                              nullptr,// SDL_Rect:更新像素的矩形区域，传nullptr表示更新整个纹理区域
                              data,// 原始像素数据
                              IMG_W),// 一行像素数据的字节数，这里传图片宽度即可
            SDL_UpdateTexture);
        // 渲染
        // 设置绘制颜色（这里随便设置了一个颜色：黄色）
        RET(SDL_SetRenderDrawColor(_renderer,255,255,0,SDL_ALPHA_OPAQUE),SDL_SetRenderDrawColor);

        // 用DrawColor清除渲染目标
        RET(SDL_RenderClear(_renderer),SDL_RenderClear);

        // 复制纹理到渲染目标上（默认是window）可以使用SDL_SetRenderTarget()修改渲染目标
        // srcrect源矩形框，dstrect目标矩形框，两者都传nullptr表示整个纹理渲染到整个目标上去
        RET(SDL_RenderCopy(_renderer,_texture,nullptr,nullptr),SDL_RenderCopy);

        // 将此前的所有需要渲染的内容更新到屏幕上
        SDL_RenderPresent(_renderer);
    }else{
        // 文件数据已经读取完毕
        killTimer(_timerId);
    }
}
